home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_09_11 / 9n11025a < prev    next >
Text File  |  1991-08-26  |  5KB  |  195 lines

  1.  
  2. void idle(unsigned priority)
  3. {
  4.     printf("idle @ %3u\n", priority);
  5. }
  6.  
  7. /* ----------------------------------------------------------- */
  8.  
  9. void pro1(unsigned priority)
  10. {
  11.     printf("pro1 @ %3u\n", priority);
  12. }
  13.  
  14. /* ----------------------------------------------------------- */
  15.  
  16. void pro2(unsigned priority)
  17. {
  18.     printf("pro2 @ %3u\n", priority);
  19. }
  20.  
  21. /* ----------------------------------------------------------- */
  22.  
  23. void pro3(unsigned priority)
  24. {
  25.     printf("pro3 @ %3u\n", priority);
  26. }
  27.  
  28. /* --------------------------------------------------------------
  29.  
  30. FUNCTION PROC_CMD: The steps to process a command are:
  31.  
  32. Note that handlers registered using signal require one int argument. 
  33. When a handler is invoked, the argument passed to it is the type of
  34. signal that caused its invocation.  Since, in this case it is always
  35. SIGINT, the argument is never used within this handler.
  36.  
  37. actions is a jump table whose index is the menu option chosen by
  38. the user.
  39.  
  40. A.  Since we have just trapped a SIGINT signal, the library will now
  41.     revert to using the SIG_DFL method for future SIGINT signals that
  42.     occur while this signal handler is executing.  This default
  43.     method generally results in the program being abnormally
  44.     terminated and that is unsuitable behavior here.  As such, we ask
  45.     to have such signals ignored until we are again ready to them.
  46.  
  47. B.  Prompt the user for their menu choice.
  48.  
  49. C.  Call the corresponding function.
  50.  
  51. D.  Reregister this handler for future SIGINT signals.
  52.  
  53. -------------------------------------------------------------- */
  54.  
  55. void proc_cmd(int dummy)
  56. {
  57.     int code;
  58.     static const void (*actions[])(void) = {
  59.         myexit,
  60.         help,
  61.         add_node
  62.  
  63.     };
  64.  
  65. /*A*/    if (signal(SIGINT, SIG_IGN) == SIG_ERR) {
  66.         fprintf(stderr, "can't ignore signal\n");
  67.         exit(EXIT_FAILURE);
  68.     }
  69.  
  70.     while (1) {
  71. /*B*/        printf("\nEnter Action Code (1 for help): ");
  72.         scanf("%d", &code);
  73.  
  74.         if (code < 0 || code >= NUMELEM(actions)) {
  75.             fprintf(stderr, "\n   Invalid command\n");
  76.             continue;
  77.         }
  78.  
  79. /*C*/        (*actions[code])();    /* call selected action */
  80.         break;
  81.     }
  82.  
  83. /*D*/    if (signal(SIGINT, proc_cmd) == SIG_ERR) {
  84.         fprintf(stderr, "can't register handler\n");
  85.         exit(EXIT_FAILURE);
  86.     }
  87. }
  88.  
  89. /* ----------------------------------------------------------- */
  90.  
  91. void myexit(void)
  92. {
  93.     exit(EXIT_SUCCESS);
  94. }
  95.  
  96. /* ----------------------------------------------------------- */
  97.  
  98. void help(void)
  99. {
  100.     printf("\n   The action codes are:\n");
  101.     printf("\t0 - Exit this program\n");
  102.     printf("\t1 - Produce this help message\n");
  103.     printf("\t2 - Add a node\n");
  104. }
  105.  
  106. /* --------------------------------------------------------------
  107.  
  108. FUNCTION ADD_NODE: The steps to add a new node to the list in
  109.     ascending alphabetic order are:
  110.  
  111. Note that process_name_table is a lookup table that allows a
  112. user-entered process name to be translated to the corresponding
  113. processing function.
  114.  
  115. A.  Get the process name and priority from the user.
  116.  
  117. B.  Get a free node from free node list.  If no more, complain and
  118.     get out.
  119.  
  120. C.  Find place to insert new node. The pointer returned from
  121.     locate_node is the address of the node after which the new 
  122.     node should be inserted.
  123.  
  124. D.  Insert new node and initialize its members. Since the list is 
  125.     maintained in decreasing order of priority, we need to update
  126.     the root pointer when a new higher priority process node
  127.     arrives. If the new node's priority equals to the current 
  128.     highest priority, the new node is inserted ahead of that
  129.     duplicate.
  130.  
  131. -------------------------------------------------------------- */
  132.  
  133. void add_node(void)
  134. {
  135.     int i;
  136.     Node *pnew_node;    /* ptr to new node */
  137.     Node *ploc_node;    /* ptr to located node */
  138.     char process_name[21];    /* selected process name */
  139.     unsigned priority;    /* function priority */
  140.     static const struct {
  141.         char *ppname;
  142.         void (*pprocess)(unsigned);
  143.     } process_name_table[] = {
  144.         {"pro1", pro1},
  145.         {"pro2", pro2},
  146.         {"pro3", pro3}
  147.     };
  148.     static unsigned highest_priority = 0;
  149.  
  150. /*A*/    while (1) {
  151.         printf("\n   Enter process name: ");
  152.         scanf("%20s", process_name);
  153.  
  154.         for (i = 0; i < NUMELEM(process_name_table); ++i) {
  155.             if (strcmp(process_name_table[i].ppname,
  156.                 process_name) == 0)
  157.                 goto found;
  158.         }
  159.  
  160.         printf("invalid process name\n");
  161.     }
  162.  
  163. found:    while (1) {
  164.         printf("\n   Enter process priority: ");
  165.         scanf("%3u", &priority);
  166.         if (priority > 0 && priority <= 100) {
  167.             break;
  168.         }
  169.  
  170.         printf("1<=priority<=100\n");
  171.     }
  172.  
  173. /*B*/    pnew_node = get_free_node();
  174.     if (pnew_node == NULL) {
  175.         printf("\n   No nodes available\n");
  176.         return;
  177.     }
  178.  
  179. /*C*/    ploc_node = locate_node(priority, INEXACT);
  180.  
  181. /*D*/    pnew_node->pfwd = ploc_node->pfwd;
  182.     pnew_node->pbwd = ploc_node;
  183.     ploc_node->pfwd = pnew_node;
  184.     pnew_node->pfwd->pbwd = pnew_node;
  185.     pnew_node->process = process_name_table[i].pprocess;
  186.     pnew_node->priority = priority;
  187.     if (priority >= highest_priority) {
  188.         proot_node = pnew_node;
  189.         highest_priority = priority;
  190.     }
  191.  
  192.     printf("   Node added\n");
  193. }
  194.  
  195.